package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.*;
import com.sky.exception.OrderBusinessException;
import com.sky.mapper.*;
import com.sky.result.PageResult;
import com.sky.service.OrdersService;
import com.sky.thirdparty.WeChatService;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class OrdersServiceImpl implements OrdersService {

    @Autowired
    private WeChatService weChatService;

    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private WebSocketServer webSocketServer;

    @Transactional
    @Override
    public OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) {
        // 1. 查询地址信息
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if (addressBook == null) {
            throw new OrderBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }

        // 2. 查询购物车信息
        Long userId = BaseContext.getCurrentId();
        ShoppingCart shoppingCartQuery = new ShoppingCart();
        shoppingCartQuery.setUserId(userId);
        List<ShoppingCart> shoppingCarts = shoppingCartMapper.list(shoppingCartQuery);
        if (shoppingCarts == null || shoppingCarts.isEmpty()) {
            throw new OrderBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        // 3. 保存下单信息
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO, orders);
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setUserId(userId);
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayStatus(Orders.UN_PAID);
        orders.setPhone(addressBook.getPhone());
        orders.setAddress(addressBook.getDetail());
        orders.setConsignee(addressBook.getConsignee());
        ordersMapper.insert(orders);

        // 4. 保存订单明细
        List<OrderDetail> orderDetails = shoppingCarts.stream().map(shoppingCart -> {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(shoppingCart, orderDetail);
            orderDetail.setOrderId(orders.getId());
            return orderDetail;
        }).collect(Collectors.toList());
        orderDetailMapper.insertBatch(orderDetails);

        // 5. 清空购物车
        ShoppingCart shoppingCartDelete = new ShoppingCart();
        shoppingCartDelete.setUserId(userId);
        shoppingCartMapper.clean(shoppingCartDelete);

        // 6. 返回订单信息
        OrderSubmitVO orderSubmitVO = new OrderSubmitVO();
        orderSubmitVO.setId(orders.getId());
        orderSubmitVO.setOrderNumber(orders.getNumber());
        orderSubmitVO.setOrderTime(orders.getOrderTime());
        orderSubmitVO.setOrderAmount(orders.getAmount());
        return orderSubmitVO;
    }

    @Override
    public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {
        // 1. 查询订单信息
        Orders orders = ordersMapper.getByNumber(ordersPaymentDTO.getOrderNumber());
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 2. 判断订单状态
        if (!Objects.equals(orders.getStatus(), Orders.PENDING_PAYMENT)) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        // 3. 判断支付状态
        if (!Objects.equals(orders.getPayStatus(), Orders.UN_PAID)) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        // 5. 微信支付
        Long userId = BaseContext.getCurrentId();
        User user = userMapper.getById(userId);
        String openid = user.getOpenid();
        JSONObject jsonObject = weChatService.pay(orders.getNumber(), orders.getAmount(), "订单支付", openid);
        if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
            throw new OrderBusinessException("该订单已支付");
        }

        // 5. 返回支付信息
        OrderPaymentVO orderPaymentVO = jsonObject.toJavaObject(OrderPaymentVO.class);
        orderPaymentVO.setPackageStr(jsonObject.getString("package"));
        return orderPaymentVO;
    }

    @Override
    public void paySuccess(String outTradeNo) {
        // 根据订单号查询订单
        Orders ordersDB = ordersMapper.getByNumber(outTradeNo);

        // 根据订单id更新订单的状态、支付方式、支付状态、结账时间
        Orders orders = Orders.builder()
                .id(ordersDB.getId())
                .status(Orders.TO_BE_CONFIRMED)
                .payStatus(Orders.PAID)
                .checkoutTime(LocalDateTime.now())
                .build();

        ordersMapper.update(orders);

        // 发送消息到WebSocket
        log.info("发送消息到WebSocket，订单号：{}", outTradeNo);
        Map<String, Object> map = new HashMap<>();
        map.put("type", 1);
        map.put("orderId", orders.getId());
        map.put("content", "订单号：" + outTradeNo);
        String message = JSON.toJSONString(map);
        webSocketServer.sendToAllClient(message);
    }

    @Override
    public PageResult historyOrders(OrdersPageQueryDTO ordersPageQueryDTO) {
        // 1. 获取当前用户id
        Long userId = BaseContext.getCurrentId();
        ordersPageQueryDTO.setUserId(userId);

        // 2. 查询分页订单
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        List<Orders> ordersList = ordersMapper.list(ordersPageQueryDTO);
        if (ordersList == null || ordersList.isEmpty()) {
            return new PageResult(0, new ArrayList<>());
        }
        PageInfo<Orders> ordersPageInfo = new PageInfo<>(ordersList);

        // 3. 查询订单明细
        List<Long> orderIds = ordersList.stream().map(Orders::getId).collect(Collectors.toList());
        List<OrderDetail> orderDetails = orderDetailMapper.listByOrderIds(orderIds);
        Map<Long, List<OrderDetail>> orderDetailMap = orderDetails.stream()
                .collect(Collectors.groupingBy(OrderDetail::getOrderId));

        // 4. 构造订单信息
        List<OrderVO> orderVOList = ordersList.stream().map(orders -> {
            OrderVO orderVO = new OrderVO();
            BeanUtils.copyProperties(orders, orderVO);
            List<OrderDetail> orderDetailList = orderDetailMap.get(orders.getId());
            orderVO.setOrderDetailList(orderDetailList);
            return orderVO;
        }).collect(Collectors.toList());
        return new PageResult(ordersPageInfo.getTotal(), orderVOList);
    }

    @Override
    public OrderVO getOrderDetail(Long orderId) {
        // 1. 查询订单信息
        Orders orders = ordersMapper.getById(orderId);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 2. 查询订单明细
        List<OrderDetail> orderDetails = orderDetailMapper.listByOrderIds(Collections.singletonList(orderId));

        // 3. 构造订单信息
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orders, orderVO);
        orderVO.setOrderDetailList(orderDetails);
        return orderVO;
    }

    @Override
    public void cancelByUser(Long orderId) throws Exception {
        // 1. 查询订单信息
        Orders orders = ordersMapper.getById(orderId);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 2. 已取消、已完成，直接返回
        if (orders.getStatus() >= Orders.COMPLETED) {
            throw new OrderBusinessException("该订单已取消或已完成");
        }

        // 3. 已接单、派送中，需要联系商家
        if (orders.getStatus() >= Orders.CONFIRMED) {
            throw new OrderBusinessException("该订单已接单或派送中，请联系商家");
        }

        // 4. 待接单，需要退款
        if (orders.getPayStatus().equals(Orders.PAID)) {
            weChatService.refund(orders.getNumber(), orders.getNumber(), orders.getAmount(), orders.getAmount());
        }

        // 5. 待支付，取消
        orders = Orders.builder().id(orders.getId())
                .status(Orders.CANCELLED)
                .cancelTime(LocalDateTime.now())
                .cancelReason("用户取消订单")
                .build();
        ordersMapper.update(orders);
    }

    @Override
    public void cancelByAdmin(OrdersCancelDTO ordersCancelDTO) throws Exception {
        // 1. 查询订单信息
        Long orderId = ordersCancelDTO.getId();
        Orders orders = ordersMapper.getById(orderId);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 2. 已取消、已完成，直接返回
        if (orders.getStatus() >= Orders.COMPLETED) {
            throw new OrderBusinessException("该订单已取消或已完成");
        }

        // 3. 待接单，需要退款
        if (orders.getPayStatus().equals(Orders.PAID)) {
            JSONObject resp = weChatService.refund(orders.getNumber(), orders.getNumber()
                    , orders.getAmount(), orders.getAmount());
            if (resp == null || resp.getString("code") == null) {
                throw new OrderBusinessException("退款失败");
            }
        }

        // 4. 待支付，取消
        orders = Orders.builder().id(orders.getId())
                .status(Orders.CANCELLED)
                .cancelTime(LocalDateTime.now())
                .cancelReason(ordersCancelDTO.getCancelReason())
                .build();
        ordersMapper.update(orders);
    }

    @Override
    public void refundSuccess(String outTradeNo) {
        // 根据订单号查询订单
        Orders ordersDB = ordersMapper.getByNumber(outTradeNo);

        // 根据订单id更新订单的状态
        Orders orders = Orders.builder()
                .id(ordersDB.getId())
                .payStatus(Orders.REFUND)
                .build();

        ordersMapper.update(orders);
    }

    @Override
    public void repetition(Long orderId) {
        // 1. 查询订单信息
        Orders orders = ordersMapper.getById(orderId);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 2. 查询订单明细
        List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(orderId);
        if (orderDetails == null || orderDetails.isEmpty()) {
            throw new OrderBusinessException("订单明细不存在");
        }

        // 3. 添加购物车
        Long userId = BaseContext.getCurrentId();
        List<ShoppingCart> shoppingCarts = orderDetails.stream().map(orderDetail -> {
            ShoppingCart shoppingCart = new ShoppingCart();
            BeanUtils.copyProperties(orderDetail, shoppingCart);
            shoppingCart.setId(null); // 必须设置为null，表示新增
            shoppingCart.setUserId(userId);
            shoppingCart.setCreateTime(LocalDateTime.now());
            return shoppingCart;
        }).collect(Collectors.toList());
        shoppingCartMapper.insertBatch(shoppingCarts);
    }

    @Override
    public PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {
        // 1. 查询分页订单
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        List<Orders> ordersList = ordersMapper.list(ordersPageQueryDTO);
        if (ordersList == null || ordersList.isEmpty()) {
            return new PageResult(0, new ArrayList<>());
        }
        PageInfo<Orders> ordersPageInfo = new PageInfo<>(ordersList);

        // 2. 查询订单明细
        List<Long> orderIds = ordersList.stream().map(Orders::getId).collect(Collectors.toList());
        List<OrderDetail> orderDetails = orderDetailMapper.listByOrderIds(orderIds);
        Map<Long, List<OrderDetail>> orderDetailMap = orderDetails.stream()
                .collect(Collectors.groupingBy(OrderDetail::getOrderId));

        // 3. 构造订单信息
        List<OrderVO> orderVOList = ordersList.stream().map(orders -> {
            OrderVO orderVO = new OrderVO();
            BeanUtils.copyProperties(orders, orderVO);
            List<OrderDetail> orderDetailList = orderDetailMap.get(orders.getId());
            if (orderDetailList != null) {
                String orderDishes = orderDetailList.stream()
                        .map(orderDetail -> orderDetail.getName() + "x" + orderDetail.getNumber())
                        .collect(Collectors.joining(", "));
                orderVO.setOrderDishes(orderDishes);
            }
            return orderVO;
        }).collect(Collectors.toList());
        return new PageResult(ordersPageInfo.getTotal(), orderVOList);
    }

    @Override
    public OrderStatisticsVO statistics() {
        // 1. 分别统计待接单、已接单、派送中的订单数量
        int toBeConfirm = ordersMapper.countStatus(Orders.TO_BE_CONFIRMED);
        int confirmed = ordersMapper.countStatus(Orders.CONFIRMED);
        int delivery = ordersMapper.countStatus(Orders.DELIVERY_IN_PROGRESS);

        // 2. 构造统计结果
        OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();
        orderStatisticsVO.setToBeConfirmed(toBeConfirm);
        orderStatisticsVO.setConfirmed(confirmed);
        orderStatisticsVO.setDeliveryInProgress(delivery);
        return orderStatisticsVO;
    }

    @Override
    public void confirm(OrdersConfirmDTO ordersConfirmDTO) {
        Orders orders = Orders.builder()
                .id(ordersConfirmDTO.getId())
                .status(Orders.CONFIRMED)
                .build();
        ordersMapper.update(orders);
    }

    @Override
    public void rejection(OrdersRejectionDTO ordersRejectionDTO) throws Exception {
        // 1. 查询订单信息
        Orders orders = ordersMapper.getById(ordersRejectionDTO.getId());
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 2. 判断订单状态
        if (!Objects.equals(orders.getStatus(), Orders.TO_BE_CONFIRMED)) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        // 3. 退款
        if (Objects.equals(orders.getPayStatus(), Orders.PAID)) {
            JSONObject resp = weChatService.refund(orders.getNumber(), orders.getNumber()
                    , orders.getAmount(), orders.getAmount());
            if (resp == null || resp.getString("code") == null) {
                throw new OrderBusinessException("退款失败");
            }
        }

        // 4. 更新订单状态
        orders = Orders.builder()
                .id(ordersRejectionDTO.getId())
                .status(Orders.CANCELLED)
                .cancelTime(LocalDateTime.now())
                .rejectionReason(ordersRejectionDTO.getRejectionReason())
                .build();
        ordersMapper.update(orders);
    }

    @Override
    public void delivery(Long orderId) {
        // 1. 查询订单信息
        Orders orders = ordersMapper.getById(orderId);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 2. 判断订单状态
        if (!Objects.equals(orders.getStatus(), Orders.CONFIRMED)) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        // 3. 更新订单状态
        orders = Orders.builder()
                .id(orderId)
                .status(Orders.DELIVERY_IN_PROGRESS)
                .build();
        ordersMapper.update(orders);
    }

    @Override
    public void complete(Long orderId) {
        // 1. 查询订单信息
        Orders orders = ordersMapper.getById(orderId);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 2. 判断订单状态
        if (!Objects.equals(orders.getStatus(), Orders.DELIVERY_IN_PROGRESS)) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        // 3. 更新订单状态
        orders = Orders.builder()
                .id(orderId)
                .status(Orders.COMPLETED)
                .deliveryTime(LocalDateTime.now())
                .build();
        ordersMapper.update(orders);
    }

    @Override
    public void reminder(Long orderId) {
        // 1. 查询订单信息
        Orders orders = ordersMapper.getById(orderId);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 2. 判断订单状态
        if (orders.getStatus() >= Orders.CONFIRMED) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        // 3. 发送催单消息
        Map<String, Object> map = new HashMap<>();
        map.put("type", 2);
        map.put("orderId", orders.getId());
        map.put("content", "订单号：" + orders.getNumber());
        String message = JSON.toJSONString(map);
        webSocketServer.sendToAllClient(message);
    }

}
